package org.itboys.weixin.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.itboys.admin.tools.AdminSessionHolder;
import org.itboys.mongodb.core.MongoDataSource;
import org.itboys.weixin.dto.WeixinUserList;
import org.itboys.weixin.entity.WeixinConfig;
import org.itboys.weixin.entity.WeixinUser;
import org.itboys.weixin.tools.WeixinUserUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Maps;

/**
 * 微信用户相关
 * @author 陈知奇
 *
 */
@Service
public class WeixinUserService extends BaseWeixinService<WeixinUser, Long> {

	private static final long serialVersionUID = 5561045273524285623L;
	
	private static  Logger logger = LoggerFactory.getLogger(WeixinUserService.class);
	
	@Autowired
	private WeixinConfigService weixinConfigService;
	
	@Resource(name="weixinDS")
	private MongoDataSource weixinUserDataSource;

	@Override
	protected MongoDataSource getMongoDataSource() {
		return weixinUserDataSource;
	}

	@Override
	protected Class<WeixinUser> getEntityClass() {
		return WeixinUser.class;
	}
	
	public void save(WeixinUser detail){
		detail.setCreateTime(new Date());
		//detail.setCreator(AdminSessionHolder.getAdminUserId());
		super.save(detail);
	}
	
	public void update(WeixinUser detail){
		WeixinUser detail2 = getById(detail.getId());
		detail.setCreateTime(detail2.getCreateTime());
		detail.setCreator(detail2.getCreator());
		//detail.setUpdater(AdminSessionHolder.getAdminUserId());
		detail.setUpdateTime(new Date());
		super.update(detail);
	}
	
	/**
	 * 根据微信ID和微信用户ID 返回微信用户的信息
	 * @param weixinId
	 * @param openid
	 * @return
	 */
	public WeixinUser getWeixinUser(long weixinId,String openid){
		Map<String, Object> param = Maps.newHashMapWithExpectedSize(2);
		param.put("weixinId", weixinId);
		param.put("openid", openid);
		List<WeixinUser> list = super.list(param);
		return list != null && !list.isEmpty() ? list.get(0):null;
	}
	
	/**
	 * 获取一个weixinId下最小的 微信用户Id
	 * select min(Id) from weixin_user where weixin_id=?
	 * @param weixinId
	 * @return
	 */
	public Long getMinUserId(long weixinId){
		Map<String, Object> param = Maps.newHashMapWithExpectedSize(2);
		param.put("weixinId", weixinId);
		param.put("orderByKey", "id");
		List<WeixinUser> list = super.list(param);
		return list != null && !list.isEmpty() ? list.get(0).getId():null;
	}
	
	/**
	 * select openid from weixin_user where weixin_id=weixinId and id>minId and status=1 order by id  limit num
	 * @param weixinId
	 * @param minId
	 * @return
	 */
	public List<String> getWeixinUsers(long weixinId,long minId,int num,int isTest){
		List<WeixinUser> list = weixinUserDataSource.createQuery(getEntityClass()).filter("weixinId", weixinId)
				.filter("id >", minId).filter("status", 1).filter("isTest", isTest).limit(num).asList();
		List<String> strings = new ArrayList<String>();
		for(WeixinUser user : list){
			strings.add(user.getOpenid());
		}
		return strings;
	}
	
	/**
	 * 根据2个ID查主键
	 * @param weixinId
	 * @param openid
	 * @return
	 */
	public Long getId(long weixinId,String openid){
		Map<String, Object> param = Maps.newHashMapWithExpectedSize(2);
		param.put("weixinId", weixinId);
		param.put("openid", openid);
		List<WeixinUser> list = super.list(param);
		return list != null && !list.isEmpty() ? list.get(0).getId():null;
	}
	
	/**
	 * 服务号全量同步微信
	 * @param weixinId
	 */
	public void doSyncWeixinUserList(final long weixinId){
		WeixinConfig config = weixinConfigService.getById(weixinId);
		if(config==null || config.getType()!=WeixinConfig.TYPE_SERVICE){
			return;
		}
		String nextOpenId = null;
		doSyncUserList(config, nextOpenId);
		/*new Thread(new Runnable() {
			@Override
			public void run() {
				WeixinConfig config = weixinConfigBO.getWeixinConfig(weixinId);
				if(config==null || config.getType()!=WeixinConfig.TYPE_SERVICE){
					return;
				}
				String nextOpenId = null;
				doSyncUserList(config, nextOpenId);
			}
		}).start();*/
	}
	
	
	private void doSyncUserList(WeixinConfig config, String nextOpenId) {
		WeixinUserList weixinUserList = WeixinUserUtils.getWeixinUserList(config.getAppId(), config.getAppSecret(), nextOpenId);
		List<String> userList = weixinUserList.getUserList();
		if(userList!=null && !userList.isEmpty()){
			for(String openid:userList){
				WeixinUser weixinUser = WeixinUserUtils.getWeixinUser(config.getAppId(), config.getAppSecret(), openid);
				if(weixinUser!=null){
					weixinUser.setWeixinId(config.getId());
					try{
						WeixinUser existUser = getWeixinUser(config.getId(), openid);
	                	if(existUser==null){
	                		save(weixinUser);
	                	}else{
	                		weixinUser.setId(existUser.getId());
	                		update(weixinUser);
	                	}
					}catch(Exception e){
						logger.error("doSyncUser error,weixinUser="+ToStringBuilder.reflectionToString(weixinUser),e);
					}
				}
			}
			if(userList.get(userList.size()-1).equals(nextOpenId)){
				doSyncUserList(config, nextOpenId);
			}
		}
	}
	
}
